package org.zjx.window.window.impl;

import com.sun.jna.platform.win32.WinDef;
import lombok.Setter;
import org.zjx.command.state.StateManager;
import org.zjx.window.action.Action;
import org.zjx.window.action.IAction;
import org.zjx.window.operation.OperationExecutor;
import org.zjx.window.operation.WindowOperation;
import org.zjx.window.window.IWindow;

import java.awt.*;
import java.awt.image.BufferedImage;
import java.util.Objects;
import java.util.concurrent.*;

/**
 * 激活专用虚拟窗口
 * 提供窗口激活的串行化执行，确保多线程环境下的窗口激活顺序
 *
 * @author zjx
 * @since 1.0
 */
public class VirtualWindow implements IWindow {

    /**
     * 目标窗口
     */
    @Setter
    private IWindow targetWindow;

    /**
     * 操作执行器
     */
    private final OperationExecutor executor;

    /**
     * 窗口名称
     */
    private final String name;

    /**
     * 激活任务队列，确保串行执行
     */
    private final BlockingQueue<ActivationTask> activationQueue = new LinkedBlockingQueue<>(100);

    /**
     * 激活处理器，单线程执行所有激活操作
     */
    private final ExecutorService activationExecutor;

    /**
     * 运行状态标志
     */
    private volatile boolean running = true;

    /**
     * 默认构造方法
     */
    public VirtualWindow() {
        this.name = "virtual-window-" + System.currentTimeMillis();
        this.executor = createDefaultExecutor();
        this.activationExecutor = createActivationExecutor();
        startActivationProcessor();
    }

    /**
     * 带目标窗口的构造方法
     *
     * @param targetWindow 目标窗口
     * @throws IllegalArgumentException 如果targetWindow为 null
     */
    public VirtualWindow(IWindow targetWindow) {
        this();
        this.targetWindow = Objects.requireNonNull(targetWindow, "目标窗口不能为 null");
    }

    /**
     * 创建默认操作执行器
     *
     * @return 操作执行器实例
     */
    protected OperationExecutor createDefaultExecutor() {
        // 返回一个基础实现，实际使用时应该注入具体的实现
        return new OperationExecutor() {
            private IWindow window;

            @Override
            public IWindow getWindow() { return window; }

            @Override
            public void setWindow(IWindow window) { this.window = window; }

            @Override
            public BufferedImage screenshot() { return null; }

            @Override
            public BufferedImage screenshot(Rectangle region) { return null; }

            @Override
            public void move(int x, int y) {}

            @Override
            public void gameMove(int x, int y) {}

            @Override
            public void gameMove(Rectangle rectangle) {}

            @Override
            public void click(int x, int y) {}

            @Override
            public void click(int button) {}

            @Override
            public void pressMouse(int button) {}

            @Override
            public void releaseMouse(int button) {}

            @Override
            public Point getMousePosition() { return new Point(0, 0); }

            @Override
            public void drag(int fromX, int fromY, int toX, int toY) {}

            @Override
            public void press(int keyCode) {}

            @Override
            public void pressKey(int keyCode) {}

            @Override
            public void releaseKey(int keyCode) {}

            @Override
            public void input(String text) {}

            @Override
            public void hotkey(int... keyCodes) {}

            @Override
            public void delay(long milliseconds) {
                try {
                    Thread.sleep(milliseconds);
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                }
            }

            @Override
            public Robot getRobot() { return null; }
        };
    }

    /**
     * 创建激活处理器
     *
     * @return 执行器服务
     */
    protected ExecutorService createActivationExecutor() {
        return Executors.newSingleThreadExecutor(r -> {
            Thread t = new Thread(r, "virtual-window-activation-processor");
            t.setDaemon(true);
            t.setUncaughtExceptionHandler((thread, throwable) -> {
                System.err.println("激活处理器异常: " + throwable.getMessage());
            });
            return t;
        });
    }

    /**
     * 启动激活处理器 - 单线程串行执行所有激活操作
     */
    private void startActivationProcessor() {
        activationExecutor.execute(() -> {
            System.out.println("激活处理器启动");

            while (running && !Thread.currentThread().isInterrupted()) {
                try {
                    ActivationTask task = activationQueue.take(); // 阻塞获取任务
                    processActivationTask(task);
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                    break;
                } catch (Exception e) {
                    System.err.println("激活处理器异常: " + e.getMessage());
                }
            }

            System.out.println("激活处理器终止");
        });
    }

    /**
     * 处理激活任务 - 串行执行，确保窗口激活有序
     *
     * @param task 激活任务
     */
    private void processActivationTask(ActivationTask task) {
        IWindow targetWindow = task.targetWindow;
        IAction action = task.action;
        WindowOperation operation = task.operation;
        CompletableFuture<Boolean> future = task.future;

        try {
            // 验证目标窗口
            if (targetWindow == null || !targetWindow.isExists()) {
                completeFuture(future, false, "目标窗口不存在");
                return;
            }

            // 1. 激活目标窗口并等待
            System.out.println("激活窗口: " + targetWindow.getTitle());
            targetWindow.activate();

            if (!targetWindow.waitForActive(2000)) {
                completeFuture(future, false, "窗口激活超时: " + targetWindow.getTitle());
                return;
            }

            // 2. 额外延迟确保窗口完全激活
            Thread.sleep(100);

            // 3. 执行任务 - 阻塞直到完成
            boolean success = false;
            if (action != null) {
                System.out.println("执行动作: " + action.getActionName());

                // 特殊处理：如果是 Action 实例，使用特殊执行方法
                if (action instanceof Action) {
                    Action concreteAction = (Action) action;
                    // 对于需要通过激活管理器执行的动作，使用特殊方法
                    success = concreteAction.executeThroughActivation();
                } else {
                    // 普通 IAction 接口
                    success = action.execute(); // 同步阻塞执行
                }
            } else if (operation != null) {
                System.out.println("执行窗口操作");
                OperationExecutor targetExecutor = targetWindow.getExecutor();
                operation.execute(targetExecutor); // 同步阻塞执行
                success = true;
            }

            completeFuture(future, success, success ? "执行成功" : "执行失败");

        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            completeFuture(future, false, "执行被中断");
        } catch (Exception e) {
            System.err.println("激活任务执行异常: " + e.getMessage());
            completeFuture(future, false, "执行异常: " + e.getMessage());
        }
    }

    /**
     * 完成 Future任务
     *
     * @param future 要完成的 Future
     * @param success 执行结果
     * @param message 结果消息
     */
    private void completeFuture(CompletableFuture<Boolean> future, boolean success, String message) {
        if (future != null) {
            if (success) {
                future.complete(true);
            } else {
                System.err.println("激活任务失败: " + message);
                future.complete(false);
            }
        }
    }

    @Override
    public void executeAction(IAction action) {
        if (targetWindow == null || action == null) {
            return;
        }

        try {
            // 同步执行：提交到队列并等待结果
            CompletableFuture<Boolean> future = new CompletableFuture<>();
            ActivationTask task = new ActivationTask(targetWindow, action, null, future);

            if (!activationQueue.offer(task, 5, TimeUnit.SECONDS)) {
                System.err.println("激活队列已满，无法执行: " + action.getActionName());
                return;
            }

            // 阻塞等待执行完成
            Boolean result = future.get(30, TimeUnit.SECONDS); // 30秒超时
            if (result == null || !result) {
                System.err.println("动作执行失败: " + action.getActionName());
            }

        } catch (TimeoutException e) {
            System.err.println("动作执行超时: " + action.getActionName());
        } catch (Exception e) {
            System.err.println("执行动作异常: " + e.getMessage());
        }
    }

    @Override
    public void execute(WindowOperation operation) {
        if (targetWindow == null || operation == null) {
            return;
        }

        try {
            // 同步执行：提交到队列并等待结果
            CompletableFuture<Boolean> future = new CompletableFuture<>();
            ActivationTask task = new ActivationTask(targetWindow, null, operation, future);

            if (!activationQueue.offer(task, 5, TimeUnit.SECONDS)) {
                System.err.println("激活队列已满，无法执行操作");
                return;
            }

            // 阻塞等待执行完成
            Boolean result = future.get(30, TimeUnit.SECONDS); // 30秒超时
            if (result == null || !result) {
                System.err.println("操作执行失败");
            }

        } catch (TimeoutException e) {
            System.err.println("操作执行超时");
        } catch (Exception e) {
            System.err.println("执行操作异常: " + e.getMessage());
        }
    }

    @Override
    public CompletableFuture<Boolean> submitAction(IAction action) {
        CompletableFuture<Boolean> future = new CompletableFuture<>();

        if (targetWindow == null || action == null) {
            future.complete(false);
            return future;
        }

        try {
            ActivationTask task = new ActivationTask(targetWindow, action, null, future);
            if (!activationQueue.offer(task, 5, TimeUnit.SECONDS)) {
                future.complete(false);
            }
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            future.complete(false);
        } catch (Exception e) {
            future.complete(false);
        }

        return future;
    }

    /**
     * 同步执行需要激活权的动作
     *
     * @param action 要执行的动作
     * @return 执行是否成功
     */
    public boolean executeWithActivationSync(IAction action) {
        try {
            CompletableFuture<Boolean> future = submitAction(action);
            return future.get(30, TimeUnit.SECONDS); // 30秒超时
        } catch (TimeoutException e) {
            System.err.println("激活执行超时: " + action.getActionName());
            return false;
        } catch (Exception e) {
            System.err.println("激活执行异常: " + e.getMessage());
            return false;
        }
    }

    /**
     * 同步执行需要激活权的窗口操作
     *
     * @param operation 要执行的操作
     */
    public void executeWithActivationSync(WindowOperation operation) {
        execute(operation); // 内部已经是同步阻塞的
    }

    @Override
    public void shutdown() {
        running = false;

        // 中断激活处理器
        activationExecutor.shutdownNow();

        // 清空队列并完成所有等待的Future
        activationQueue.clear();

        System.out.println("虚拟窗口已关闭");
    }

    @Override
    public String getName() {
        return name;
    }

    @Override
    public WinDef.HWND getHwnd() {
        return targetWindow != null ? targetWindow.getHwnd() : new WinDef.HWND();
    }

    @Override
    public String getTitle() {
        return targetWindow != null ? targetWindow.getTitle() : "VirtualWindow";
    }

    @Override
    public boolean isExists() {
        return targetWindow != null && targetWindow.isExists();
    }

    @Override
    public Rectangle getBounds() {
        return targetWindow != null ? targetWindow.getBounds() : new Rectangle(0, 0, 1, 1);
    }

    @Override
    public Rectangle getTrueBounds() {
        return targetWindow != null ? targetWindow.getTrueBounds() : new Rectangle(0, 0, 1, 1);
    }

    @Override
    public void activate() {
        if (targetWindow != null) {
            targetWindow.activate();
        }
    }

    @Override
    public boolean isActive() {
        return targetWindow != null && targetWindow.isActive();
    }

    @Override
    public boolean waitForActive(long timeoutMs) {
        return targetWindow != null && targetWindow.waitForActive(timeoutMs);
    }

    @Override
    public void close() {
        if (targetWindow != null) {
            targetWindow.close();
        }
    }

    @Override
    public StateManager getState() {
        return targetWindow != null ? targetWindow.getState() : new StateManager();
    }

    @Override
    public void updateState() {
        if (targetWindow != null) {
            targetWindow.updateState();
        }
    }

    @Override
    public BufferedImage getScreenshot() {
        return targetWindow.getScreenshot();
    }

    @Override
    public void flushScreenshot() {
        targetWindow.flushScreenshot();
    }

    @Override
    public OperationExecutor getExecutor() {
        return targetWindow != null ? targetWindow.getExecutor() : executor;
    }

    @Override
    public void start() {
        // 虚拟窗口不需要额外的启动逻辑
    }

    @Override
    public boolean isRunning() {
        return running;
    }

    @Override
    public boolean isValid() {
        return targetWindow != null && targetWindow.isValid() && running;
    }

    @Override
    public boolean awaitTermination(long timeout, TimeUnit unit) throws InterruptedException {
        return activationExecutor.awaitTermination(timeout, unit);
    }

    /**
     * 获取激活队列大小
     *
     * @return 当前激活队列中的任务数量
     */
    public int getActivationQueueSize() {
        return activationQueue.size();
    }

    /**
     * 激活任务封装
     */
    private static class ActivationTask {
        final IWindow targetWindow;
        final IAction action;
        final WindowOperation operation;
        final CompletableFuture<Boolean> future;

        ActivationTask(IWindow targetWindow, IAction action, WindowOperation operation, CompletableFuture<Boolean> future) {
            this.targetWindow = targetWindow;
            this.action = action;
            this.operation = operation;
            this.future = future;
        }
    }
}